package com.jxaummd.mushroom.core.util.tool.encrypt;

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class EncryptUntil {
    public static String data="86118256705494";
    public static  String publicKeyString =  "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALijkEyq3XFjFAIQUarvO7RGZnbETJ/wRLd6qzGWXXPx6s4X4A6zwYYbGLZZr24BxDVhybKjfOTzisIl7P1lWX8CAwEAAQ==";
    public static String privateKeyString = "MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAuKOQTKrdcWMUAhBRqu87tEZmdsRMn/BEt3qrMZZdc/HqzhfgDrPBhhsYtlmvbgHENWHJsqN85POKwiXs/WVZfwIDAQABAkB1AOFeVCCDy99P93tpMLTK5pnjxT0xVRaWlpuJjtmlsKDR9iLiHQKa59IR+4FeTxyEo5QHv8FQhtuLPHyYAy8hAiEA7/IhyHZQ9HaxaEt51Z+dH9QMA1S1GD1PQchVsUA0g/cCIQDE/h4UleiY3LQPggejgCdm02v8kR7GlxiN2q8VTubkuQIgY+/VYkjlLuzAt0+4TuFL8BXBayG8y3u9pwhpqIm1VcECIE9lVF5bpSmnGnN9pvKA/mB1Kfrbypmj4GOcFiDyciERAiBfREqSADbBsDZAtamKl5TyZadLhQHS9rBWBP80Dco1Cw==";
    private static PublicKey publicKey = null ;   // getPublicKey(publicKeyString);
    private static PrivateKey privateKey = null; //getPrivateKey(privateKeyString);


    //生成密钥对
    public static KeyPair genKeyPair(int keyLength) throws Exception{
        KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(512);
        return keyPairGenerator.generateKeyPair();
    }



    //公钥加密
    public static byte[] encrypt(byte[] content, PublicKey publicKey) throws Exception{
        Cipher cipher=Cipher.getInstance("RSA");//java默认"RSA"="RSA/ECB/PKCS1Padding"
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(content);
    }

    //私钥解密
    public static byte[] decrypt(byte[] content, PrivateKey privateKey) throws Exception{
        Cipher cipher=Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(content);
    }

    //将base64编码后的公钥字符串转成PublicKey实例
    public static PublicKey getPublicKey(String publicKey) throws Exception{
        byte[ ] keyBytes= Base64.getDecoder().decode(publicKey.getBytes("UTF-8"));
        X509EncodedKeySpec keySpec=new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory=KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(keySpec);
    }

    //将base64编码后的私钥字符串转成PrivateKey实例
    public static PrivateKey getPrivateKey(String privateKey) throws Exception{
        byte[ ] keyBytes=Base64.getDecoder().decode(privateKey.getBytes("UTF-8"));
        PKCS8EncodedKeySpec keySpec=new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory=KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    private static final char HEX_DIGITS[] =
            {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    private static String bytes2HexString(final byte[] bytes) {
        if (bytes == null) return "";
        int len = bytes.length;
        if (len <= 0) return "";
        char[] ret = new char[len << 1];
        for (int i = 0, j = 0; i < len; i++) {
            ret[j++] = HEX_DIGITS[bytes[i] >>> 4 & 0x0f];
            ret[j++] = HEX_DIGITS[bytes[i] & 0x0f];
        }
        return new String(ret);
    }

    private static byte[] hexString2Bytes(String hexString) {
        if (isSpace(hexString)) return null;
        int len = hexString.length();
        if (len % 2 != 0) {
            hexString = "0" + hexString;
            len = len + 1;
        }
        char[] hexBytes = hexString.toUpperCase().toCharArray();
        byte[] ret = new byte[len >> 1];
        for (int i = 0; i < len; i += 2) {
            ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1]));
        }
        return ret;
    }

    private static boolean isSpace(final String s) {
        if (s == null) return true;
        for (int i = 0, len = s.length(); i < len; ++i) {
            if (!Character.isWhitespace(s.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    private static int hex2Dec(final char hexChar) {
        if (hexChar >= '0' && hexChar <= '9') {
            return hexChar - '0';
        } else if (hexChar >= 'A' && hexChar <= 'F') {
            return hexChar - 'A' + 10;
        } else {
            throw new IllegalArgumentException();
        }
    }

    private static PublicKey getPubKey()  {
        if(publicKey == null){
            try {
                publicKey = getPublicKey(publicKeyString);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return publicKey;
    }

    private static PrivateKey getPriKey() {
        if(privateKey == null){
            try {
                privateKey = getPrivateKey(privateKeyString);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return privateKey;
    }


    /**
     * 这个方法将正常的字符串转换成已经加了密的
     * @param string
     * @return
     * @throws Exception
     */
    private  static String EncrypteAESHexString(String string) throws Exception {
        string = bytes2HexString(encrypt(string.getBytes("UTF-8"),getPubKey()));
        return string;
    }

    /**
     * 这个方法将hex的字符串转换成正常的字符串
     * @param hexString
     * @return
     * @throws Exception
     */
    private  static String DecryptAESHexString(String hexString) throws Exception {
        hexString = new String(decrypt(hexString2Bytes(hexString),getPriKey()));
        return hexString;
    }


    /**
     * 6adc4005685f3afee1a23591645e17e1
     * 7c9842bad04769efcab9443c67a15dd2
     * AES 加密
     */
    private static String secretkey = "myUniversityssss";

    private static Key key;

    private static Cipher cipher;

    private static byte[] bytes;

    //加密函数
    public static String EncryptAES(String str) {
        try {
            Common();
            //初始化
            cipher.init(Cipher.ENCRYPT_MODE, key);
            bytes = cipher.doFinal(str.getBytes("UTF-8"));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //将加密的bytes数组转化为十六进制的字符串并返回
        return bytes2HexString(bytes);
    }

    /**
     * 解密函数
     * @param str   是16进制字符
     */
    public static String DecipheringAES(String str) {
        try {
            Common();
            bytes = hexString2Bytes(str);
            cipher.init(Cipher.DECRYPT_MODE, key);
            bytes = cipher.doFinal(bytes);
            return (new String(bytes,"UTF-8"));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return str;
    }

    /**
     * 公共类,加密和解密度需要的
     */
    public static void Common(){
        try {
            //生成Key
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            //初始化,加密秘钥
            keyGenerator.init(128,new SecureRandom(secretkey.getBytes("UTF-8")));
            //生成key
            SecretKey secretKey = keyGenerator.generateKey();
            //
            byte[] bytesKey = secretKey.getEncoded();
            //key转换
            key = new SecretKeySpec(secretkey.getBytes("UTF-8"),"AES");
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }



    public static void main(String[] arg) throws Exception {
        // TODO Auto-generated method stub

        String str1 = EncrypteAESHexString(data);
        System.out.println(str1);
        System.out.println(DecryptAESHexString(str1));


        String str2 = EncrypteAESHexString(data);
        System.out.println(str2);
        System.out.println(DecryptAESHexString(str2));


        //该str为十六进制的字符
        String string = EncryptAES("20172107");
        System.out.println(string);
        String asd = string;
        //解密必须传入的是十六进制的字符
        System.out.println(DecipheringAES("68433846E08E0238453F1FC3B29C77068AE861839CE8E446F310B6320E97E2148326C81EE02A9CECA10F65A1F3C6A9736492618B93C5033E843CA1185E49F6BB3F6B590022F558411CCA076EC3922FBC6F913E11CFFEE89C947BCFBF99F763EC4CAE8FD2D13C6CE43E9EF0131A7DEDD81A9EEE75CD6357E314477C0DA6C9087FDC884A3CA099A1E09C34268FBA94FC7A431C44BA0243A6EE4764040804D208BB086353AB5B9513B8817C059FD1872B94BBC810A09CA75E83A0AD0483B7FA9F7A53C6594B1FA612F46E90303A1E6B4D57ED4162058B7DD9D8238EB20434B34C817E04683FC3570183B3C5C30B455DA4B52DC41C530D3560068F9E630D5E7C04D765928E0D65CD0E3CBAABA8EF85D6D0BDC271EED2FA5E3B1AB38AA1F2274487DB"));

    }

}
